home *** CD-ROM | disk | FTP | other *** search
- /*
- WaitSeconds.c
-
- Accurate delay that yields time to other processes. Exits if user types command-period.
-
- Giving up time to the Mac OS is good, but dicey, since it might take more than the
- number of ticks that we offered.
-
- Checking whether the user hit Command-Period is good, but dicey, for the same reason.
- That check calls EventAvail, which gives up time to the Mac OS.
-
- Our solution is to give up time (and check for cmd-.) while we have lots of time
- (more than 1/2 s), and to just run a tight loop, checking Seconds(), during the
- final countdown. This gives us the best of both worlds. Accurate timing, yet
- allow other processes to run during long waits, and allow user to cancel long waits.
-
- REFERENCE:
- TechNote 1083 Weak-linking to a Code Fragment Manager-based shared library
- http://devworld.apple.com/dev/technotes/tn/tn1083.html
-
- HISTORY:
- 2/3/97 dgp wrote it, for use in David Brainard's Psychophysics Toolbox for MATLAB.
- 3/10/97 dgp use the new CommandPeriod.c, which doesn't discard keyDown events.
- Moved WaitNextEventOrQuit() to CommandPeriod.c
- 3/15/97 dgp Call neither WNE nor CommandPeriod during final 1/2 s.
- 4/15/97 dgp Don't call WNE if priority is raised, because there won't be any ticks.
- 4/18/97 dgp Return immediately if timer is nonfunctional.
- 7/9/97 dgp Simplified the test for availability of UpTime, based on TN1083.
- */
-
- #include "VideoToolbox.h"
- #if GENERATINGCFM
- #ifndef __CODEFRAGMENTS__
- #include <CodeFragments.h>
- #endif
- #endif
- typedef UnsignedWide AbsoluteTime; // Types.h
- extern AbsoluteTime UpTime(void); // DriverServices.h
-
- void WaitSeconds(double secs)
- {
- double finishSecs,ticks; // ticks is double to avoid overflow problems
- EventRecord event;
- Boolean wne,haveUpTime;
-
- #if GENERATINGCFM && GENERATINGPOWERPC
- haveUpTime= (Ptr)UpTime != (Ptr)kUnresolvedCFragSymbolAddress;
- #else
- haveUpTime=0;
- #endif
- if(IsNan(secs) || secs<0)return;
- if(GetPriority()>0 && !haveUpTime)return;
- finishSecs=Seconds()+secs;
- for(wne=0;;wne=!wne){
- ticks=60.15*(finishSecs-Seconds());
- if(ticks<=0.)break;
- if(ticks>=30.)switch(wne && GetPriority()==0){ // don't fool around close to the end.
- default:
- case 1:
- WaitNextEvent(0,&event,6,NULL); // be a good citizen, share 1/10 s.
- break;
- case 0:
- if(CommandPeriod()){ // calls EventAvail, which gives up time
- #if MATLAB
- PrintfExit("User typed cmd-. EXITING.");
- #else
- PrintfExit("\nUser typed cmd-. EXITING.\n");
- #endif
- }
- break;
- }
- }
- }
-
-